package com.stark.wechat.service.impl;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.dom4j.DocumentException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.stark.wechat.domain.User;
import com.stark.wechat.enums.MessageType;
import com.stark.wechat.message.response.Article;
import com.stark.wechat.message.response.NewsMessage;
import com.stark.wechat.message.response.TextMessage;
import com.stark.wechat.util.SysTools;
import com.stark.wechat.util.WechatUtil;

/**
 * 微信接入业务处理。
 * @author Ben
 * @since 1.0.0
 * @version 1.0.0, 2017/8/6
 */
@Service("accessService")
public class AccessServiceImpl {
	Logger logger = LoggerFactory.getLogger(AccessServiceImpl.class);
	
	@Autowired
	private UserServiceImpl userService;
	
	/**
	 * 微信接入验证。
	 * @param signature 微信加密签名， signature 结合了开发者填写的 token 参数和请求中的 timestamp 参数、 nonce 参数。
	 * @param timestamp 时间戳。
	 * @param nonce 随机数。
	 * @param echostr 随机字符串。
	 * @return 验证通过时原样返回 echostr ，否则返回其他任意字符串。
	 */
	public String validate(String signature, String timestamp, String nonce, String echostr) {
		String token = SysTools.getToken();
		String str = WechatUtil.validateAccess(signature, timestamp, nonce, echostr, token);
		return str;
	}
	
	/**
	 * 处理微信消息请求。
	 * @param request HTTP 请求对象。
	 * @return 本地处理结果。
	 * @throws IOException 获取输入流时抛出异常。
	 * @throws DocumentException 读取 XML 时抛出异常。
	 */
	public String handelRequest(HttpServletRequest request) throws IOException, DocumentException {
        // xml请求解析
        Map<String, String> requestMap = WechatUtil.parseXmlRequest(request);
        String fromUserName = requestMap.get("FromUserName");	// 发送方帐号（一个OpenID）
        String toUserName = requestMap.get("ToUserName");	// 开发者微信号
        String msgType = requestMap.get("MsgType");	// 消息类型

        String result = "success";
        if (msgType.equals(MessageType.REQUEST_TEXT.getCode())) {	// 文本消息
        		// TODO:业务逻辑代码
        } else if (msgType.equals(MessageType.REQUEST_IMAGE.getCode())) {	// 图片消息
        		// TODO:业务逻辑代码
        } else if (msgType.equals(MessageType.REQUEST_VOICE.getCode())) {	// 音频消息
        		// TODO:业务逻辑代码
        } else if (msgType.equals(MessageType.REQUEST_SHORTVIDEO.getCode())) {	// 短视频信息
        		// TODO:业务逻辑代码
        } else if (msgType.equals(MessageType.REQUEST_VIDEO.getCode())) {	// 视频信息
        		// TODO:业务逻辑代码
        } else if (msgType.equals(MessageType.REQUEST_LOCATION.getCode())) {	// 地理位置消息
        		// TODO:业务逻辑代码
        } else if (msgType.equals(MessageType.REQUEST_LINK.getCode())) {	// 链接消息
        		// TODO:业务逻辑代码
        } else if (msgType.equals(MessageType.REQUEST_EVENT.getCode())) {	// 事件推送
	        	// 事件类型
	        	String event = requestMap.get("Event");
            if (event.equals(MessageType.EVENT_SUBSCRIBE.getCode())) {	// 订阅
            		User user = this.userService.get(fromUserName);
            		if (user != null) {	// 如果用户之前关注过，则启用用户
            			this.userService.enable(fromUserName);
            		} else {
            			user = new User();
            			user.setOpenId(fromUserName);
            			this.userService.add(user);
            		}
	            	
	            	// 组织绑定案件url
	        		String appURL = SysTools.getAppURL();
	        		// 组织图文列表
	        		List<Article> articleList = new ArrayList<Article>();
	        		Article article = new Article();
	            	article.setTitle("欢迎关注公众号");
	            	article.setDescription("一生至少该有一次，为了某个人而忘了自己，不求有结果，不求同行，不求曾经拥有，甚至不求你爱我。只求在我最美的年华里，遇到你。");
	            	article.setPicUrl(appURL + "resources/img/i_love_you.png");
	            	article.setUrl(WechatUtil.formatOauth2URL(SysTools.getAppId(), appURL, "snsapi_base", null));
	            	articleList.add(article);
	            	// 组织图文消息
	            	NewsMessage newsMsg = new NewsMessage();
	            	newsMsg.setToUserName(fromUserName);
	            	newsMsg.setFromUserName(toUserName);
	            	newsMsg.setCreateTime(new Date().getTime());
	            	newsMsg.setMsgType(MessageType.RESPONSE_NEWS.getCode());
	            	newsMsg.setArticleCount(1);
	            	newsMsg.setArticles(articleList);
	            	
	            	String xmlStr = WechatUtil.messageToXml(newsMsg);
	            	return xmlStr;
            } else if (event.equals(MessageType.EVENT_UNSUBSCRIBE.getCode())) {	// 取消订阅
            		this.userService.disable(fromUserName);
            } else if (event.equals(MessageType.EVENT_SCAN.getCode())) {	// 扫描带参数二维码
            		// TODO:业务逻辑代码
            } else if (event.equals(MessageType.EVENT_LOCATION.getCode())) {	// 上报地理位置
            		// TODO:业务逻辑代码
            } else if (event.equals(MessageType.EVENT_CLICK.getCode())) {	// 点击菜单拉取消息
            		// TODO:业务逻辑代码
            } else if (event.equals(MessageType.EVENT_VIEW.getCode())) {	// 点击菜单跳转链接
            		// TODO:业务逻辑代码
            } else if (event.equals(MessageType.EVENT_TEMPLATESENDJOBFINISH.getCode())) {		// 模板消息送达结束
	            	String msgId  = requestMap.get("MsgID");
	            	String status = requestMap.get("Status");
	            	if ("success".equalsIgnoreCase(status)) {
	            		System.out.println("模板消息送达成功：MsgID=" + msgId);
	            	} else {
	            		if ("failed:user block".equalsIgnoreCase(status)) {
	            			logger.error("模板消息送达失败：MsgID={},status={}",
	            					msgId, "送达失败，用户设置拒绝接收公众号消息！");
		            	} else if ("failed: system failed".equals(status)) {
		            		logger.error("模板消息送达失败：MsgID={},status={}",
	            					msgId, "送达失败，送达由于其他原因失败！");
		            	}
	            	}
            }
        }

        // 回复文本消息
        TextMessage textMessage = new TextMessage();
        textMessage.setToUserName(fromUserName);
	    	textMessage.setFromUserName(toUserName);
	    	textMessage.setCreateTime(new Date().getTime());
	    	textMessage.setMsgType(MessageType.RESPONSE_TEXT.getCode());
	    	textMessage.setContent(result);
	    	String xmlStr = WechatUtil.messageToXml(textMessage);
	    	return xmlStr;
	}
}
